import os
import threading
import time

import uvicorn
from dotenv import load_dotenv

from common.http import ok_response
from common.log import get_logger
from common.time import get_datetime_now
from device.app import create_device_app
from device.update_data import update_data
from device.utils.dlt645 import DLT645F2007Protocol

load_dotenv(".env.device.dlt645")

DLT645_PORT = os.getenv("DLT645_PORT")
DLT645_ADDR = os.getenv("DLT645_ADDR")
RESOURCE_ID = os.getenv("RESOURCE_ID")
OPERATOR_CODE = os.getenv("OPERATOR_CODE")
GATEWAY = os.getenv("GATEWAY")
RESOURCE_HOST = os.getenv("RESOURCE_HOST")
logger = get_logger("dlt645_detect")


def resource_info(data_json: dict):
    return {
        "resourceId": RESOURCE_ID,
        "acquisitionTime": get_datetime_now(),
        "data": {
            "maxupCapacity": 0,
            "maxdownCapacity": 0,
            "maxupRate": 0,
            "maxdownRate": 0,
            "maxupLength": 0,
            "maxdownLength": 0,
            "controlState": 0,
            "data": data_json
        },
        "resourceName": "dlt645",
        "resourceType": 3,
        "resourceState": "3",  # 2表示测试，3表示投运，4表示退役，5表示停机
        "maxAdjustablePower": 0,
        "assesmentMeterbox": "dlt645",
        "listingNumber": "dlt645",
        "RatedCapacity": 0,
        "RatedPower": 0,
        "RatedVoltage": 0,
        "Longitude": 0,
        "Latitude": 0,
        "operatorCode": OPERATOR_CODE,
        "resourceHost": RESOURCE_HOST
    }


def detect():
    dlt = DLT645F2007Protocol(logger, DLT645_ADDR, DLT645_PORT)
    ret = dlt.send_cmd()
    if not ret:
        logger.error("detect failed")
        return {
            "P": 0,
            "Q": 0,
            "Pa": 0,
            "Qa": 0,
            "Ua": 0,
            "Ia": 0
        }
    return {
        "P": ret.all_power,
        "Q": 0,
        "Pa": ret.all_power,
        "Qa": 0,
        "Ua": ret.A_voltage,
        "Ia": ret.A_current
    }


def detect_loop():
    while True:
        dlt645_data = detect()
        logger.info(dlt645_data)
        try:
            if update_data(GATEWAY, resource_info(dlt645_data)):
                logger.info("update data success")
            else:
                logger.error("update data failed")
        except Exception as e:
            logger.error(e)
        time.sleep(60)


def control_handler(payload):
    logger.info(payload)
    return ok_response(None)


app = create_device_app(control_handler)

if __name__ == "__main__":
    threading.Thread(target=detect_loop, daemon=True).start()
    if os.getenv("IPV6"):
        host = "::"
    else:
        host = os.getenv("HOST", "0.0.0.0")
    port = int(os.getenv("PORT", "8001"))
    uvicorn.run(app, host=host, port=port)
